package com.bj58.mis.apm.collector.jvm;


import com.bj58.mis.apm.collector.BaseSchedulableCollector;


import java.lang.management.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class JVMCollector  extends BaseSchedulableCollector<JVMModel> {

    public JVMModel collector(){
        JVMModel jvmModel=new JVMModel();
        collectorGc(jvmModel);
        collectorMemory(jvmModel);
        collectorMemoryPool(jvmModel);
        collectorClassLoadingInfo(jvmModel);
        collectorJVMInfo(jvmModel);
        collectorThreadInfo(jvmModel);
        super.collect(jvmModel);
        return jvmModel;
    }

    private void collectorJVMInfo(JVMModel model){
        Properties props = System.getProperties();
        model.setJavahome(String.valueOf(props.get("java.home")));
        model.setVendor(String.valueOf(props.get("java.vendor")));
        model.setVersion(String.valueOf(props.get("java.version")));
    }

    private void collectorGc(JVMModel model){
        List<GarbageCollectorMXBean> gcmbeans = ManagementFactory.getGarbageCollectorMXBeans();

        for (GarbageCollectorMXBean gc : gcmbeans) {
            Map<String,String> map=new HashMap<String,String>();
            map.put("name",gc.getName());
            map.put("Count",String.valueOf(gc.getCollectionCount()));
            map.put("GCTime",String.valueOf(gc.getCollectionTime()/1000));
            model.getGc().add(map);
        }
    }

    private void collectorMemory(JVMModel model){
        MemoryMXBean memory = ManagementFactory.getMemoryMXBean();
        MemoryUsage heap=memory.getHeapMemoryUsage();
        MemoryUsage nonHeap=memory.getNonHeapMemoryUsage();

        model.getHeap().put("committed",heap.getCommitted());
        model.getHeap().put("init",heap.getInit());
        model.getHeap().put("max",heap.getMax());
        model.getHeap().put("used",heap.getUsed());

        model.getNonHeap().put("committed",nonHeap.getCommitted());
        model.getNonHeap().put("init",nonHeap.getInit());
        model.getNonHeap().put("max",nonHeap.getMax());
        model.getNonHeap().put("used",nonHeap.getUsed());
    }

    public void collectorMemoryPool(JVMModel model){
        List<MemoryPoolMXBean> memoryPoolList=ManagementFactory.getMemoryPoolMXBeans();
        for(MemoryPoolMXBean memoryPoolMXBean : memoryPoolList){
            MemoryUsage memoryUsage=           memoryPoolMXBean.getUsage();
            Map<String,String> map=new HashMap<String,String>();

            map.put("name",memoryPoolMXBean.getName());
            map.put("committed", String.valueOf(memoryUsage.getCommitted()));
            map.put("init", String.valueOf(memoryUsage.getInit()));
            map.put("max", String.valueOf(memoryUsage.getMax()));
            map.put("used", String.valueOf(memoryUsage.getUsed()));
            model.getMemoryPool().add(map);
        }
    }

    public void collectorClassLoadingInfo(JVMModel jvmModel){
        ClassLoadingMXBean classLoadingMXBean    =    ManagementFactory.getClassLoadingMXBean();

        jvmModel.getClassLoadingInfo().put("LoadedClassCount", Long.valueOf(classLoadingMXBean.getLoadedClassCount()));
        jvmModel.getClassLoadingInfo().put("TotalLoadedClassCount",classLoadingMXBean.getTotalLoadedClassCount());
        jvmModel.getClassLoadingInfo().put("UnloadedClassCount",classLoadingMXBean.getUnloadedClassCount());
    }

    public void collectorThreadInfo(JVMModel model){
        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        model.getThreadInfo().put("TotalStartedThreadCount",threadBean.getTotalStartedThreadCount());
        model.getThreadInfo().put("DaemonThreadCount", Long.valueOf(threadBean.getDaemonThreadCount()));
        model.getThreadInfo().put("PeakThreadCount", Long.valueOf(threadBean.getPeakThreadCount()));
        model.getThreadInfo().put("CurrentThreadCount", Long.valueOf(threadBean.getThreadCount()));

    }

    public static void main(String[] args) throws InterruptedException {


    }

    @Override
    public void schedule() {
        collector();
    }
}
